#pragma once

#include "noncopyable.h"
#include "Acceptor.h"
#include "InetAddress.h"
#include "TcpConnection.h"
#include "Buffer.h"
#include "Callbacks.h"
#include "EventLoopThreadPool.h"
#include "EventLoop.h"

#include <functional>
#include <string>
#include <memory>
#include <atomic>
#include <unordered_map>

class TcpServer : noncopyable
{
public:
    using ThreadInitCallback = std::function<void(EventLoop *)>;

    enum Option
    {
        kNoReusePort,
        kReusePort
    };

    // 构造析构
    TcpServer(EventLoop *loop, const InetAddress &listenAddr, const std::string &nameArg, Option option = kNoReusePort);
    ~TcpServer();
    // 设置线程池数量
    void setThreadNum(int numThreads);
    // 启动服务器
    void start();

    // 设置回调函数
    void setThreadInitcallback(const ThreadInitCallback &cb)
    {
        threadInitCallback_ = cb;
    }
    void setConnectionCallback(const ConnectionCallback &cb)
    {
        connectionCallback_ = cb;
    }
    void setMessageCallback(const MessageCallback &cb)
    {
        messageCallback_ = cb;
    }
    void setWriteCompleteCallback(const WriteCompleteCallback &cb)
    {
        writeCompleteCallback_ = cb;
    }

private:
    // 创建和移除链接
    void newConnecion(int sockfd, const InetAddress &peerAddr);
    void removeConnecion(const TcpConnectionPtr &conn);
    void removeConnecionInLoop(const TcpConnectionPtr &conn);

    using ConnecionMap = std::unordered_map<std::string, TcpConnectionPtr>;

    EventLoop *loop_; // baseloop

    const std::string ipPort_;
    const std::string name_;

    std::unique_ptr<Acceptor> acceptor_; // baseloop上的acceptor

    std::shared_ptr<EventLoopThreadPool> threadPool_;

    ConnectionCallback connectionCallback_;
    MessageCallback messageCallback_;
    WriteCompleteCallback writeCompleteCallback_;

    ThreadInitCallback threadInitCallback_;

    std::atomic_int started_;

    int nextConnId_;
    ConnecionMap connections_; // 保存链接信息
};